package com.putong35.common.httprequest.retrofit.converter;

import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.google.gson.Gson;
import com.google.gson.internal.$Gson$Types;
import com.putong35.common.httprequest.retrofit.ResponseData;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import okhttp3.ResponseBody;
import retrofit2.Converter;

/**
 * 创建时间：2018/4/3
 * 编写人： chengxin
 * 功能描述：json解析相关
 */
public class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
    private final Gson gson;
    private final Type type;
    private Class<T> clazz;

    public GsonResponseBodyConverter(Gson gson, Type type) {
        this.type = type;
        this.gson = gson;
    }
    public GsonResponseBodyConverter(Gson gson, Type type, Class<T> cls) {
        this.type = type;
        this.gson = gson;
        this.clazz = cls;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T convert(@NonNull ResponseBody value) throws IOException {
        Class<?> rawType = $Gson$Types.getRawType(type);
        if (ResponseBody.class == rawType) {
            return (T) value;
        }

        String cacheStr = value.string();
        try {
            JSONObject jsonObject = new JSONObject(cacheStr);
            final int code = jsonObject.getInt("code");
            final String msg = jsonObject.getString("message");
            ResponseData tip = new ResponseData(code, msg);
            if (code != 1) {
                throw new HttpError(msg, tip);
            }

           /* if (ResponseData.class == rawType) {
                return (T) tip;
            }*/
            Object data = jsonObject.get("data");
            if (data == JSONObject.NULL) {
                //in case
                throw new HttpError("暂无数据", tip);
            }
            //如果是String 直接返回
            if (String.class == rawType) {
                return (T) data.toString();
            }
            //data 为Boolean 如{"msg": "手机号格式错误","code": 0,"data": false}
            if (Boolean.class == rawType && data instanceof Boolean) {
                return (T) data;
            }
            //data 为Integer  如{"msg": "手机号格式错误","code": 0,"data": 12}
            if (Integer.class == rawType && data instanceof Integer) {
                return (T) data;
            }

            //list data
            String listStr = jsonObject.getJSONObject("data").optString("list");
            if (!TextUtils.isEmpty(listStr)) {
                T t = gson.fromJson(listStr, type);
                if (t != null) {
                    //防止线上接口修改导致反序列化失败奔溃
                    return t;
                }
            }

            T t = gson.fromJson(data.toString(), type);
            if (t != null) {
                //防止线上接口修改导致反序列化失败奔溃
                return t;
            }
            throw new HttpError("数据异常", tip);
        } catch (JSONException e) {
            throw new HttpError("解析异常", cacheStr);
        }
    }

    public List<T> convertList(@NonNull ResponseBody value) throws IOException {
        Class<?> rawType = $Gson$Types.getRawType(type);
        String cacheStr = value.string();
        try {
            JSONObject jsonObject = new JSONObject(cacheStr);
            final int code = jsonObject.getInt("code");
            final String msg = jsonObject.getString("message");
            ResponseData tip = new ResponseData(code, msg);
            if (code != 1) {
                throw new HttpError(msg, tip);
            }

            Object data = jsonObject.get("data");
            if (data == JSONObject.NULL) {
                //in case
                throw new HttpError("暂无数据", tip);
            }


            //list data
            String listStr = jsonObject.getJSONObject("data").optString("list");
            if (!TextUtils.isEmpty(listStr)) {

                JSONArray array = jsonObject.getJSONObject("data").optJSONArray("list");
                List<T> beanList = new ArrayList<>();
                if (array != null && array.length() > 0) {
                    Gson gson = new Gson();
                    for (int i = 0; i < array.length(); i++) {
                        T bean = (T)gson.fromJson(array.opt(i).toString(), clazz);
                        beanList.add(bean);
                    }
                }
                return beanList;
            }

            throw new HttpError("数据异常", tip);
        } catch (JSONException e) {
            throw new HttpError("解析异常", cacheStr);
        }
    }
}